перейти к содержанию

Как использовать селекторы XPath для парсинга веб-страниц в Python

Если вы хотите извлечь данные из веб-страниц с помощью Python, XPath — это важный инструмент, который должен быть в вашем наборе инструментов для парсинга веб-страниц. XPath предоставляет возможность перемещаться по HTML-структуре страницы и точно определять нужные элементы и данные.

В этом руководстве мы рассмотрим основы XPath и продемонстрируем, как вы можете использовать его возможности для парсинга веб-страниц с помощью Python. К концу вы будете готовы решать широкий спектр задач по очистке данных, используя XPath для хирургического извлечения нужных вам данных.

Что такое XPath?

XPath означает язык XML Path. Это язык запросов для выбора узлов из документа XML или HTML. С помощью XPath вы указываете шаблон, соответствующий структуре документа, и он возвращает все элементы, соответствующие этому шаблону.

Хотя XPath изначально был разработан для XML, он так же хорошо работает с HTML, что делает его идеальным для целей веб-скрапинга. Он предоставляет более мощную и гибкую альтернативу селекторам CSS или регулярным выражениям.

Основы синтаксиса XPath

Чтобы начать использовать XPath, вам необходимо понять строительные блоки синтаксиса XPath. Вот ключевые понятия:

Выбор узлов по имени тега

Самое простое выражение XPath — просто указать имя тега. Например:

  • //h1 выбирает все <h1> элементы заголовка на странице
  • //p выбирает все <p> элементы абзаца
  • //img выбирает все <img> элементы изображения

Выбор узлов по атрибуту

Вы можете выбрать элементы, имеющие определенный атрибут или значение атрибута, используя @ синтаксис:

  • //*[@class="highlighted"] выбирает все элементы, у которых класс «выделен»
  • //a[@href] выбирает все <a> элементы привязки, имеющие атрибут href
  • //img[@alt="Logo"] выбирает <img> элементы с альтернативным текстом «Логотип»

Выбор узлов по положению

Вы можете выбирать узлы в зависимости от их положения, используя квадратные скобки. [] и числовой индекс:

  • //ul/li[1] выбирает первый <li> элемент внутри каждого <ul> неупорядоченный список
  • //table/tr[last()] выбирает последний <tr> строка в каждом <table>
  • //ol/li[position() <= 3] выбирает первые три <li> предметы в каждом <ol> упорядоченный список

Выбор узлов по отношению

XPath позволяет перемещаться вверх и вниз по дереву документа, чтобы выбирать элементы на основе их предков, потомков, братьев и сестер и т. д.:

  • //div[@class="content"]/* выбирает все дочерние элементы <div> элементы с классом «контент»
  • //p/.. выбирает родительские элементы всех <p> пункты
  • //h1/following-sibling::p выбирает все <p> элементы, которые являются братьями и сестрами после <h1> Заголовок
  • //section//img выбирает все <img> элементы, являющиеся потомками <section> на любом уровне

Предикаты и функции

XPath поддерживает широкий спектр предикатов и функций для дальнейшего уточнения вашего выбора:

  • //p[contains(text(),"scrapy")] выбирает <p> элементы, содержащие текст «скрапи»
  • //a[starts-with(@href,"https")] выбирает <a> элементы, у которых href начинается с «https»
  • //ul[count(li) > 10] выбирает <ul> элементы, содержащие более 10 <li> пункты
  • //img[string-length(@alt) > 0] выбирает <img> элементы с непустым атрибутом alt

Использование XPath с lxml и BeautifulSoup

Теперь, когда вы понимаете основы синтаксиса XPath, давайте посмотрим, как его можно использовать в Python с популярными библиотеками lxml и BeautifulSoup. Мы рассмотрим пример очистки текста основного заголовка с домашней страницы ScrapingBee.

Анализ HTML с помощью lxml и BeautifulSoup

Во-первых, нам нужно получить HTML-код веб-страницы с помощью библиотеки запросов и проанализировать его в древовидную структуру, которую мы можем запросить с помощью XPath. Мы будем использовать BeautifulSoup для анализа HTML и lxml для оценки наших выражений XPath:

import requests
from bs4 import BeautifulSoup
from lxml import etree

html = requests.get("https://scrapingbee.com") 
soup = BeautifulSoup(html.text, "html.parser")
dom = etree.HTML(str(soup))

Мы тут:

  1. Получите HTML, используя requests.get()
  2. Разберите строку HTML в объект BeautifulSoup, используя html.parser.
  3. Преобразуйте объект BeautifulSoup в строку, чтобы мы могли проанализировать его с помощью lxml. etree.HTML() функция
  4. Разобрать строку в lxml Element объект, который мы можем запросить с помощью XPath

Создание и оценка выражений XPath

Теперь, когда у нас есть проанализированное дерево HTML, мы можем создать выражение XPath для выбора основного <h1> заголовок на странице:

heading_xpath = ‘//h1‘

Чтобы сравнить этот XPath с нашим проанализированным HTML-документом, мы используем метод xpath() Метод:

heading_elements = dom.xpath(heading_xpath)

Ассоциация dom.xpath() вызов вернет список всех элементов, соответствующих нашему селектору XPath. В этом случае должно быть только одно совпадение. <h1> элемент.

Извлечение текста и атрибутов

Получив ссылку на элемент, мы можем легко извлечь его текст и любые атрибуты, используя свойства lxml:

heading_text = heading_elements[0].text
print(heading_text)
# Tired of getting blocked while scraping the web?  

Мы успешно извлекли текст заголовка с помощью всего лишь одной строки XPath! Мы также могли бы получить доступ к значениям атрибутов элемента, используя get():

heading_id = heading_elements[0].get(‘id‘)  

Использование XPath с Selenium

Альтернативный подход — использовать Selenium для автоматизации и очистки динамических веб-сайтов, требующих JavaScript. Selenium предоставляет собственные методы для выбора элементов с помощью строк XPath.

Настройка Selenium WebDriver

Чтобы начать работу с Selenium, сначала необходимо установить пакет Selenium и веб-драйвер для браузера, который вы хотите использовать. Вот как вы можете настроить драйвер Chrome:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver_path = "/path/to/chromedriver"  
driver = webdriver.Chrome(driver_path)

Обязательно загрузите соответствующую версию ChromeDriver для вашей установки Chrome и укажите путь к исполняемому файлу.

Поиск элементов с помощью XPath

Настроив драйвер, мы можем перейти на веб-страницу и начать поиск элементов. WebDriver Selenium предоставляет find_element метод, который принимает локатор XPath:

driver.get("https://scrapingbee.com")

heading_xpath = "//h1"
heading_element = driver.find_element(By.XPATH, heading_xpath)

Как и в примере с lxml, здесь будет найден первый <h1> элемент на странице. Если вы хотите найти все элементы, соответствующие XPath, используйте find_elements вместо:

paragraph_xpath = "//p"
paragraph_elements = driver.find_elements(By.XPATH, paragraph_xpath)  

Извлечение текста и атрибутов

Имея ссылку на веб-элемент, вы можете получить доступ к его свойствам, таким как текстовое содержимое и атрибуты:

heading_text = heading_element.text
print(heading_text)  
# Tired of getting blocked while scraping the web?

paragraph_id = paragraph_elements[0].get_attribute("id")

Извлечение данных с помощью Selenium и XPath довольно простое, но имейте в виду, что Selenium обычно работает медленнее, чем использование простой библиотеки HTTP-запросов, поскольку он запускает настоящий браузер.

Советы и рекомендации

Когда вы начнете использовать XPath для парсинга веб-страниц, вам следует запомнить несколько советов и рекомендаций:

Используйте Chrome DevTools для тестирования выражений XPath

При создании селекторов XPath очень полезно протестировать их в интерактивном режиме, чтобы убедиться, что они соответствуют вашим ожиданиям. Chrome DevTools предоставляет простой способ сделать это:

  1. Щелкните элемент правой кнопкой мыши и выберите «Проверить», чтобы открыть панель «Элементы DevTools».
  2. Нажмите Ctrl+F, чтобы открыть окно поиска.
  3. Введите выражение XPath, чтобы выделить соответствующие элементы на странице.

Обработка противоречивой разметки

Веб-сайты часто имеют противоречивую или неправильную HTML-разметку, которая может сбить с толку ваши селекторы XPath. Рекомендуется использовать такую ​​библиотеку, как BeautifulSoup, для очистки и нормализации HTML перед его анализом с помощью lxml.

Напишите надежный и удобный в обслуживании XPath

Чтобы свести к минимуму вероятность поломки вашего парсера из-за изменений макета на целевом сайте, постарайтесь писать выражения XPath как можно более конкретными, но не более конкретными, чем необходимо. Отдавайте предпочтение выбору по семантическим свойствам, таким как имена тегов, идентификаторы и атрибуты данных, а не полагаясь на конкретную структуру разметки.

Также неплохо разбить сложные выражения XPath на переменные с описательными именами, чтобы улучшить читаемость и удобство обслуживания.

Кэшируйте результаты для повышения производительности

Если вы очищаете большие объемы данных или несколько раз посещаете одни и те же страницы, рассмотрите возможность кэширования результатов анализа HTML и XPath, чтобы избежать ненужных сетевых запросов и накладных расходов на анализ. Для кэширования вы можете использовать простой словарь или более надежное решение, такое как MongoDB или Redis.

Заключение

XPath — невероятно мощный инструмент для точного извлечения данных из HTML-страниц. Обладая базовым пониманием синтаксиса и способностью переводить селекторы CSS в их эквиваленты XPath, вы сможете выполнять широкий спектр задач по очистке веб-страниц.

Библиотеки Python, такие как lxml, BeautifulSoup и Selenium, предоставляют простые способы интеграции XPath в ваши рабочие процессы парсинга. В зависимости от ваших конкретных потребностей и характеристик целевого сайта вы можете выбрать наиболее подходящий подход.

Продолжая парсинг веб-страниц с помощью Python и XPath, всегда соблюдайте условия обслуживания веб-сайта и ограничения файла robots.txt. И не забудьте освежить в памяти основы функций и операторов XPath — вы будете поражены тем, как многого можно достичь с помощью всего лишь нескольких строк умного XPath!

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *